<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DeepSeek 聊天记录智能导出工具</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            background-color: #f0f2f5;
            color: #333;
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            box-sizing: border-box;
        }
        .container {
            background-color: #fff;
            padding: 25px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.1);
            width: 100%;
            max-width: 800px;
            box-sizing: border-box;
            display: flex;
            flex-direction: column;
        }
        h1 {
            text-align: center;
            color: #1a1a1a;
            margin-top: 0;
            margin-bottom: 20px;
            font-size: 24px;
        }
        #file-input {
            display: none;
        }
        .file-label {
            display: block;
            padding: 30px 15px;
            border: 2px dashed #ddd;
            border-radius: 8px;
            cursor: pointer;
            text-align: center;
            color: #888;
            transition: all 0.2s ease-in-out;
            margin-bottom: 15px;
        }
        .file-label strong { color: #3964fe; }
        .file-label:hover {
            border-color: #3964fe;
            background-color: #f0f5ff;
        }
        .controls {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        .options-group {
            padding: 10px 15px;
            background-color: #f8f9fa;
            border-radius: 8px;
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        .options-group legend {
            font-weight: 500;
            padding-bottom: 5px;
        }
        .radio-group label, .checkbox-group label {
            cursor: pointer;
            display: flex;
            align-items: center;
        }
        .radio-group input, .checkbox-group input {
            margin-right: 5px;
        }
        .checkbox-group label.disabled {
            color: #aaa;
            cursor: not-allowed;
        }
        #extract-button {
            padding: 10px 20px;
            border: none;
            background-color: #3964fe;
            color: white;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 500;
            transition: background-color 0.2s;
            height: fit-content;
            margin-top: auto;
            margin-bottom: auto;
        }
        #extract-button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        #extract-button:not(:disabled):hover {
            background-color: #2a4ac8;
        }
        .result-section {
            display: flex;
            flex-direction: column;
            flex-grow: 1;
        }
        #result-textarea {
            width: 100%;
            flex-grow: 1;
            min-height: 350px;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 15px;
            box-sizing: border-box;
            font-size: 14px;
            line-height: 1.6;
            resize: vertical;
            background-color: #fafafa;
        }
        #download-button {
            margin-top: 15px;
            align-self: flex-end;
            padding: 10px 20px;
            border: none;
            background-color: #22c55e;
            color: white;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 500;
            display: none;
            transition: background-color 0.2s;
        }
        #download-button:hover {
            background-color: #1a9c4a;
        }
        #status-message {
            text-align: center;
            margin: -10px 0 15px 0;
            font-style: italic;
            color: #666;
            min-height: 20px;
            font-size: 14px;
        }
        /* -- Footer Style - Refined -- */
        footer {
            margin-top: 25px;
            padding-top: 15px;
            border-top: 1px solid #eee;
            text-align: center;
            font-size: 12px;
            color: #888;
        }
        footer p {
            margin: 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>DeepSeek 聊天记录智能导出工具</h1>
        
        <label for="file-input" class="file-label" id="file-label">
            <strong>点击此处选择文件</strong><br>
            <span id="file-name-display" style="font-size: 12px;">支持 Edge/Chrome 网页快照 (.mhtml, .html)</span>
        </label>
        <input type="file" id="file-input" accept=".mhtml,.html,.txt">
        
        <div class="controls">
            <div class="options-group">
                <legend>导出格式</legend>
                <div class="radio-group">
                    <label><input type="radio" name="format" value="txt" id="format-txt" checked> TXT</label>
                    <label><input type="radio" name="format" value="json" id="format-json"> JSON</label>
                </div>
            </div>
            <div class="options-group">
                <legend>选项</legend>
                <div class="checkbox-group">
                    <label id="thinking-label"><input type="checkbox" id="include-thinking" checked> 包含助手思维链</label>
                </div>
            </div>
            <button id="extract-button" disabled>开始提取</button>
        </div>
        
        <div id="status-message"></div>
        
        <div class="result-section">
            <textarea id="result-textarea" placeholder="转换结果将显示在这里..." readonly></textarea>
            <button id="download-button">下载文件</button>
        </div>

        <!-- -- Footer HTML - Refined -- -->
        <footer>
            <p>作者: Yancy</p>
        </footer>
    </div>

    <script>
        const fileInput = document.getElementById('file-input');
        const extractButton = document.getElementById('extract-button');
        const downloadButton = document.getElementById('download-button');
        const resultTextarea = document.getElementById('result-textarea');
        const statusMessage = document.getElementById('status-message');
        const fileNameDisplay = document.getElementById('file-name-display');
        const includeThinkingCheckbox = document.getElementById('include-thinking');
        const thinkingLabel = document.getElementById('thinking-label');
        const formatRadios = document.querySelectorAll('input[name="format"]');

        let originalFileName = 'chat-export';
        let fileContentCache = null;
        let parsedData = { title: null, messages: [] };

        fileInput.addEventListener('change', (event) => {
            const file = event.target.files[0];
            if (!file) { return; }

            originalFileName = file.name.split('.').slice(0, -1).join('.') || 'chat-export';
            fileNameDisplay.textContent = file.name;
            extractButton.disabled = false;
            statusMessage.textContent = '文件已选择，请点击“开始提取”。';
            resultTextarea.value = '';
            downloadButton.style.display = 'none';
            fileContentCache = null;
            parsedData = { title: null, messages: [] };
        });

        extractButton.addEventListener('click', () => {
            const file = fileInput.files[0];
            if (!file) {
                statusMessage.textContent = '请先选择一个文件。';
                return;
            }

            extractButton.disabled = true;
            statusMessage.textContent = '正在读取和解析文件...';

            const reader = new FileReader();
            reader.onload = (e) => {
                try {
                    fileContentCache = e.target.result;
                    parsedData = parseChatData(fileContentCache);
                    const outputText = formatOutput(parsedData);
                    
                    resultTextarea.value = outputText;
                    statusMessage.textContent = '🎉 解析完成！';
                    if (outputText && !outputText.startsWith('错误')) {
                        downloadButton.style.display = 'block';
                    }
                } catch (error) {
                    const errorMessage = `错误: ${error.message}`;
                    resultTextarea.value = errorMessage;
                    statusMessage.textContent = '解析失败，请检查文件格式。';
                    console.error("解析错误:", error);
                } finally {
                    extractButton.disabled = false;
                }
            };
            
            reader.onerror = () => {
                 const errorMessage = '错误: 读取文件失败！';
                 resultTextarea.value = errorMessage;
                 statusMessage.textContent = errorMessage;
                 extractButton.disabled = false;
            };
            reader.readAsText(file, 'UTF-8');
        });

        formatRadios.forEach(radio => radio.addEventListener('change', () => {
            const isJson = document.getElementById('format-json').checked;
            includeThinkingCheckbox.disabled = isJson;
            thinkingLabel.classList.toggle('disabled', isJson);

            if (parsedData.messages.length > 0) {
                resultTextarea.value = formatOutput(parsedData);
            }
        }));

        includeThinkingCheckbox.addEventListener('change', () => {
            if (parsedData.messages.length > 0) {
                resultTextarea.value = formatOutput(parsedData);
            }
        });

        downloadButton.addEventListener('click', () => {
            if (!resultTextarea.value || resultTextarea.value.startsWith('错误')) {
                alert('没有有效内容可供下载。');
                return;
            }
            
            const isJson = document.getElementById('format-json').checked;
            const fileExtension = isJson ? '.json' : '.txt';
            const mimeType = isJson ? 'application/json;charset=utf-8' : 'text/plain;charset=utf-8';

            const blob = new Blob([resultTextarea.value], { type: mimeType });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${originalFileName}${fileExtension}`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        });

        // --- Core Functions ---

        function extractHtmlFromMhtml(mhtmlContent) {
            const htmlMarker = 'Content-Type: text/html';
            const htmlStartIndex = mhtmlContent.indexOf(htmlMarker);
            if (htmlStartIndex === -1) {
                if(mhtmlContent.trim().toLowerCase().startsWith('<!doctype html') || mhtmlContent.trim().toLowerCase().startsWith('<html')) return mhtmlContent;
                throw new Error("文件格式无法识别。请确认是 .mhtml 或 .html 文件。");
            }
            let contentStartIndex = mhtmlContent.indexOf('<', htmlStartIndex);
            if (contentStartIndex === -1) throw new Error("在 mhtml 中找不到有效的 HTML 内容。");
            const boundaryMatch = mhtmlContent.match(/------MultipartBoundary--[a-zA-Z0-9]+----/);
            if (!boundaryMatch) return mhtmlContent.substring(contentStartIndex);
            const boundary = boundaryMatch[0];
            const contentEndIndex = mhtmlContent.indexOf(boundary, contentStartIndex);
            return mhtmlContent.substring(contentStartIndex, contentEndIndex > -1 ? contentEndIndex : mhtmlContent.length);
        }

        function parseChatData(fileContent) {
            const htmlString = extractHtmlFromMhtml(fileContent);
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlString, 'text/html');

            const title = doc.querySelector('title')?.innerText.replace('- DeepSeek', '').trim() || "未命名对话";
            const messages = [];
            
            const allUserWrappers = doc.querySelectorAll('div[data-um-id]');
            if (allUserWrappers.length === 0) {
                 throw new Error("未找到任何聊天记录。请确认文件内容是否正确。");
            }

            for (const userWrapper of allUserWrappers) {
                const userMessageDiv = userWrapper.querySelector('.ds-message');
                if (userMessageDiv) {
                    const userText = userMessageDiv.textContent?.trim();
                    if (userText) {
                        messages.push({ role: 'user', content: userText });
                    }
                }

                const assistantWrapper = userWrapper.nextElementSibling;
                if (assistantWrapper && assistantWrapper.querySelector('.ds-message')) {
                    const thinkingText = assistantWrapper.querySelector('.ds-think-content .ds-markdown')?.textContent?.trim() || null;
                    let finalReply = '';

                    const finalReplyMarkdowns = assistantWrapper.querySelectorAll('.ds-markdown');
                    for (const markdown of finalReplyMarkdowns) {
                        if (!markdown.closest('.ds-think-content')) {
                            finalReply = markdown.textContent?.trim();
                            if (finalReply) break;
                        }
                    }
                    if(finalReply) {
                       messages.push({ role: 'assistant', content: finalReply, thinking: thinkingText });
                    }
                }
            }
            return { title, messages };
        }

        function formatOutput(data) {
            const isJson = document.getElementById('format-json').checked;
            
            if (isJson) {
                const apiMessages = data.messages.map(({ role, content }) => ({ role, content }));
                return JSON.stringify(apiMessages, null, 2);
            } else {
                const exportedChat = [];
                exportedChat.push(`会话标题: ${data.title}\n`);
                exportedChat.push('='.repeat(50));
                exportedChat.push('');

                data.messages.forEach(msg => {
                    if (msg.role === 'user') {
                        exportedChat.push(`[USER]\n${msg.content}`);
                    } else if (msg.role === 'assistant') {
                        if (includeThinkingCheckbox.checked && msg.thinking) {
                            exportedChat.push(`[ASSISTANT (Thinking)]\n${msg.thinking}\n`);
                        }
                        exportedChat.push(`[ASSISTANT]\n${msg.content}\n`);
                    }
                    exportedChat.push('-'.repeat(30));
                    exportedChat.push('');
                });
                
                while(exportedChat.length > 0 && (exportedChat[exportedChat.length - 1] === '' || exportedChat[exportedChat.length - 1].startsWith('-'.repeat(30)))) {
                    exportedChat.pop();
                }

                if (data.messages.length === 0) {
                    return "错误：找到了网页结构，但未能提取到具体的聊天内容。";
                }
                
                return exportedChat.join('\n');
            }
        }
    </script>
</body>
</html>